package com.iot.service.mqtt.service.acl;

import lombok.extern.slf4j.Slf4j;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Author: hszhou
 * @Date: 2025/5/14 9:49
 * @Description: 必须描述类做什么事情, 实现什么功能
 */
@Slf4j
public class AclConfigParser {

    public static List<AclRule> parse(String configPath) {
        try (InputStream is = AclConfigParser.class.getClassLoader().getResourceAsStream(configPath)) {
            return new BufferedReader(
                    new InputStreamReader(is, StandardCharsets.UTF_8))
                    .lines()
                    .filter(line -> !line.startsWith("#") && !line.trim().isEmpty())
                    .map(line -> {
                        String[] parts = line.split("\\|");
                        AclRule rule = new AclRule();

                        // 解析主体类型和值
                        String[] principal = parts[0].trim().split(":");
                        rule.setPrincipalType(principal[0].trim());
                        rule.setPrincipals(Arrays.stream(principal[1].split(","))
                                .map(String::trim)
                                .collect(Collectors.toSet()));

                        // 解析主题
                        String[] resource = parts[1].trim().split(":");
                        rule.setTopics(Arrays.stream(resource[1].split(","))
                                .map(String::trim)
                                .collect(Collectors.toSet()));
                        // 解析操作
                        rule.setAction(parts[2].trim().toLowerCase());

                        // 解析权限
                        rule.setAllow("allow".equals(parts[3].trim().toLowerCase()));

                        return rule;
                    }).collect(Collectors.toList());
        } catch (IOException e) {
            e.printStackTrace();
            log.error("文件不存在");
        }
        return new ArrayList<>();
    }


    public static List<AclRule> parse(Path configPath) throws IOException {
        return Files.lines(configPath)
                .filter(line -> !line.startsWith("#") && !line.trim().isEmpty())
                .map(line -> {
                    String[] parts = line.split("\\|");
                    AclRule rule = new AclRule();

                    // 解析主体类型和值
                    String[] principal = parts[0].trim().split(":");
                    rule.setPrincipalType(principal[0].trim());
                    rule.setPrincipals(Arrays.stream(principal[1].split(","))
                            .map(String::trim)
                            .collect(Collectors.toSet()));

                    // 解析主题
                    String[] resource = parts[1].trim().split(":");
                    rule.setTopics(Arrays.stream(resource[1].split(","))
                            .map(String::trim)
                            .collect(Collectors.toSet()));


                    // 解析操作
                    rule.setAction(parts[2].trim().toLowerCase());

                    // 解析权限
                    rule.setAllow("allow".equals(parts[3].trim().toLowerCase()));

                    return rule;
                }).collect(Collectors.toList());
    }

    public static boolean matches(Set<String> topics, String topic) {
       return topics.stream().map(e->e
                .replace("+", "[^/]+")
                .replace("#", ".*")
                .replace("$", "\\$"))
                .anyMatch(topic::matches);
    }
}
